package com.rexolar.openapi.utlis;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.rexolar.openapi.constants.Constants;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.text.MessageFormat;
import java.util.*;

/**
 * @author zhusiyu
 * @description:  MD5加密
 * @date 2019-12-25
 **/
@Slf4j
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class HttpUtil {

    public static Map<String, String> paramsToMap(HttpServletRequest httpServletRequest) {
        try {
            String requestMethod = httpServletRequest.getMethod();
            if (Constants.HTTP_METHOD_GET.equals(requestMethod)) {
                return paramsToMap(httpServletRequest.getQueryString());
            } else {
                RequestWrapper request = new RequestWrapper(httpServletRequest);
                return request.getBodyMap();
            }
        } catch (Exception e) {
            log.error("paramsToMap error", e);
            return Collections.emptyMap();
        }

    }

    public static Map<String, String> paramsToMap(String params) {
        if (StringUtils.isBlank(params)) {
            return Collections.emptyMap();
        }
        try {
            Map<String, String> map = new LinkedHashMap<>();
            if (params.startsWith(SYMBOL_BRACE_LEFT) && params.endsWith(SYMBOL_BRACE_RIGHT)) {
                //是{ 开头， } 结尾，则认为是json
                JSONObject jsonParams = JSONObject.parseObject(params);
                Iterator iter = jsonParams.entrySet().iterator();
                String encodeParams = null;
                while (iter.hasNext()) {
                    Map.Entry entry = (Map.Entry) iter.next();
                    if(entry.getValue()!=null && String.valueOf(entry.getValue()).contains("%")){
                        if(UrlEncoderUtils.hasUrlEncoded(entry.getValue().toString())){
                            encodeParams = decode(StringUtils.toStringTrim(params));
                            break;
                        }
                    }
                }

                if(StringUtils.isBlank(encodeParams)){
                    parseByJson(params, map);
                }else{
                    parseByJson(encodeParams, map);
                }
            } else {
                String decodeParam = decode(StringUtils.toStringTrim(params));
                if (StringUtils.isBlank(decodeParam)) {
                    return Collections.emptyMap();
                }
                parseByString(decodeParam, map);
            }

            return map;
        } catch (Exception e) {
            log.error(MessageFormat.format("paramsToMap by params:{0} error", params), e);
            return Collections.emptyMap();
        }

    }


    /**
     * json格式转map
     * @param decodeParam
     * @param map
     */
    public static void parseByJson(String decodeParam, Map<String, String> map) {
        JSONObject paramObj = JSONObject.parseObject(decodeParam, Feature.OrderedField);
        paramObj.forEach((key, value) -> {
            if (Objects.isNull(value)) {
                map.put(key, null);
            } else {
                map.put(key, String.valueOf(value));
            }
        });

    }

    /**
     * 字符串拼接形式
     * @param decodeParam
     * @param map
     */
    private static void parseByString(String decodeParam, Map<String, String> map) {
        String[] array = decodeParam.split(Constants.SYMBOL_AND);
        for (String pair : array) {
            //如果为空，获取只有 =，或者没有 = 认为参数残缺，直接跳过
            if (StringUtils.isBlank(pair) || Constants.SYMBOL_EQUAL.equals(pair.trim())
                    || !pair.contains(Constants.SYMBOL_EQUAL)) {

                continue;
            }
            int len = pair.indexOf(Constants.SYMBOL_EQUAL);
            String param = pair.substring(0, len);
            if (len + 1 >= pair.length()) {
                map.put(param, null);
            } else {
                String value = pair.substring(pair.indexOf(Constants.SYMBOL_EQUAL) + 1);
                map.put(param, value);
            }
        }
    }

    /**
     * 编码格式转换
     * @param content
     * @return
     */
    public static String decode(String content) {
        if (StringUtils.isBlank(content)) {
            return "";
        }
        try {
            content = content.replaceAll("%(?![0-9a-fA-F]{2})", "%25");
            return URLDecoder.decode(content, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            log.error("HttpUtil decode error", e);
        }
        return "";
    }



    public static String buildQuery(JSONObject param) {
        final StringBuilder query = new StringBuilder();
        param.forEach((key, value) -> query.append(Constants.SYMBOL_AND).append(key)
                .append(Constants.SYMBOL_EQUAL)
                .append(URLEncoder.encode(value.toString())));

        return query.toString().replaceFirst(Constants.SYMBOL_AND, Constants.BLANK_STRING);
    }
    private static final String SYMBOL_BRACE_LEFT = "{";
    private static final String SYMBOL_BRACE_RIGHT = "}";

}
